//
//  tcsf/nreq.h
//  Created by tommywang on 13-4-28.
//

#ifndef _tcsf_nreq_h_
#define _tcsf_nreq_h_

#include <ostream>
using namespace std;
#include "net/btypes.h"
#include "net/socket.h"
#include "mem/small_buffer.h"
using namespace tdl;
#include "btypes.h"
using namespace tcsf;

namespace tcsf {
///////////////
template <size_t MAX_SIZE>
struct nreq
{
public:
	tdl::socket			local_sock;
	
	tdl::host_addr		peer_ha;

	tdl::small_buffer<MAX_SIZE>	data;

public:
	size_t length() const
	{
		return sizeof(tdl::socket) + sizeof(host_addr) + sizeof(size_t) + data.len;
	}

	void serialize(char* p) const
	{
//		::memcpy(p, &local_sock, sizeof(tdl::socket));		p += sizeof(tdl::socket);
//		::memcpy(p, &peer_ha, sizeof(tdl::host_addr));		p += sizeof(tdl::host_addr);
		*(tdl::socket*)p = local_sock;	p += sizeof(tdl::socket);
		*(host_addr*)p = peer_ha;	p += sizeof(host_addr);
		*(size_t*)p = data.len;		p += sizeof(size_t);
		::memcpy(p, data.ptr, data.len);
	}

	void deserialize(const char* p)
	{
//		::memcpy(&local_sock, p, sizeof(tdl::socket));		p += sizeof(tdl::socket);
//		::memcpy(&peer_ha, p, sizeof(tdl::host_addr));		p += sizeof(tdl::host_addr);
		local_sock = *(tdl::socket*)p;	p += sizeof(tdl::socket);
		peer_ha = *(host_addr*)p;		p += sizeof(host_addr);
		data.len = *(size_t*)p;			p += sizeof(size_t);
		if(data.len > data.size)
			return;
		::memcpy(data.ptr, p, data.len);
	}

	friend std::ostream& operator<<(std::ostream& ost, const nreq& req)
	{
		ost << req.peer_ha << '|' 
			<< string(req.data.ptr, req.data.len);

		return ost;
	}
};

typedef nreq<NREQ_BUFFER_MAX_LEN>		nreq_type;
////////////////////
}	// namespace tcsf
#endif


